<template>
  <v-layout type="main">
    <!-- <p class="page-title">强化学习开发</p> -->
    <div class="detail-layout">
      <br />
      <el-form
        class="form myself-form alick-add-form"
        ref="form"
        :model="addForm"
        :rules="submitRules"
        label-width="120px"
      >
        <div v-if="active == 1 || active == 9">
          <h3 class="add-alike-title">基本信息</h3>
          <el-form-item label="名称" prop="name">
            <el-input type="text" maxlength="40" v-model="addForm.name" />
          </el-form-item>
          <el-form-item label="描述" prop="desc">
            <el-input type="textarea" maxlength="200" :rows="3" v-model="addForm.desc" />
          </el-form-item>
          <el-form-item label="配图">
            <media-uploader
              accept=".jpg, .jpeg, .png, .JPG, .JPEG"
              :src="addForm.avatar"
              @avatarPath="avatarPath"
            />
          </el-form-item>
          <el-form-item label="评估工具" prop="evaluationTool">
            <el-checkbox-group v-model="addForm.evaluationTool" @change="handleCheckedCitiesChange">
              <el-checkbox label="Tensorboard">Tensorboard</el-checkbox>
              <el-checkbox label="PyTorchProfiler">PyTorchProfiler</el-checkbox>
              <el-checkbox label="TensorFlowProfiler">TensorFlowProfiler</el-checkbox>
            </el-checkbox-group>
          </el-form-item>

          <!-- <h3 class="add-alike-title">网络结构设置</h3> -->
          <!-- <h3 class="add-alike-title">参数设置</h3> -->
          <h3 class="add-alike-title">网络设置</h3>
          <el-form-item label="网络模型" prop="network_structure">
            <el-select
              v-model="addForm.network_structure"
              style="width:100%;"
              :popper-append-to-body="false"
              @change="changeStructure"
              filterable
              allow-create
              popper-class="select-popper"
              placeholder="请选择"
            >
              <!--              <el-option v-for="item in network_structureOptions" :key="item.value" :label="item.label"-->
              <!--                         :value="item.value">-->
              <!--              </el-option>-->
              <el-option
                v-for="item in network"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>

          <h3 class="add-alike-title">算法</h3>
          <el-form-item label="算法名称" prop="algorithm_name">
            <!-- <el-select v-model="addForm.algorithm_name" style="width:100%;" :popper-append-to-body="false"
                filterable allow-create popper-class="select-popper" placeholder="请选择">
                <el-option v-for="item in algorithms" :key="item.value" :label="item.label" :value="item.value">
                </el-option>
            </el-select>-->
            <!--            <el-cascader v-model="addForm.algorithm_name" :options="algorithms" :show-all-levels="false"-->
            <!--                         class="full-extent-select"></el-cascader>-->

            <el-select
              v-model="addForm.algorithm_name"
              style="width:100%;"
              :popper-append-to-body="false"
              @change="changeStructure"
              filterable
              allow-create
              popper-class="select-popper"
              placeholder="请选择"
            >
              <el-option
                v-for="item in algorithms"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>

          <h3 class="add-alike-title">仿真环境配置</h3>
          <el-form-item label="仿真测试环境" prop="simulation_node_group">
            <el-select
              v-model="simulation.image_id"
              @change="changeSimulationImage()"
              prop="simulation_image_id"
              class="full-extent-select"
            >
              <el-option
                v-for="item in simulationImageOptions"
                :value="item.id"
                :label="item.name"
                :key="item.id"
              ></el-option>
            </el-select>
            <!-- <el-cascader v-model="simulation.image_id" :options="simulationImageOptions"
            :show-all-levels="false" class="full-extent-select"></el-cascader>-->
          </el-form-item>


          <h3 class="add-alike-title">超参设置</h3>
          <el-form-item label="探索策略" prop="exploration_strategy">
            <el-select
              v-model="addForm.exploration_strategy"
              style="width:100%;"
              @change="changeOptimizer"
              popper-class="select-popper"
              placeholder="请选择"
            >
              <el-option
                v-for="item in exploration"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>

          <!-- <el-form-item label="网络参数设置" prop="network_parameter">
              <el-select v-model="addForm.network_parameter" style="width:100%;" :popper-append-to-body="false"
                  filterable allow-create popper-class="select-popper" placeholder="请选择">
                  <el-option v-for="item in network_parameter" :key="item.value" :label="item.label"
                      :value="item.value">
                  </el-option>
              </el-select>
          </el-form-item>-->
          <!-- <el-form-item :label="item.label" :prop="network_parameter[item.value]"
              v-for="(item, i) in this.network_parameter" :key="i">
              <el-input-number v-model="addForm.network_parameter[item.value]" :min="1"
                  v-if="item.type === 'number'" />

              <el-select v-model="addForm.network_parameter[item.value]" style="width:100%;"
                  @change="changeActiveFunc" popper-class="select-popper" placeholder="请选择"
                  v-if="item.type === 'select'">
                  <el-option v-for="item in activeFunc" :key="item.value" :label="item.label" :value="item.value">
                  </el-option>
              </el-select>

              <el-radio v-model="addForm.network_parameter[item.value]" :label="true"
                  v-if="item.type === 'click'">开启</el-radio>
              <el-radio v-model="addForm.network_parameter[item.value]" :label="false"
                  v-if="item.type === 'click'">关闭</el-radio>
          </el-form-item>-->

          <!-- <h3 class="add-alike-title">超参数设置</h3> -->

          <!-- <h3 class="add-alike-title">网络优化策略</h3> -->

          <el-form-item label="训练策略(网络优化策略)" prop="optimizer">
            <el-select
              v-model="addForm.optimizer"
              style="width:100%;"
              @change="changeOptimizer"
              popper-class="select-popper"
              placeholder="请选择"
            >
              <!--              <el-option v-for="item in optimizers" :key="item.value" :label="item.label" :value="item.value">-->
              <!--              </el-option>-->
              <el-option
                v-for="item in optimizer"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>

          <el-form-item label="经验缓存处理策略" prop="optimizer">
            <el-select
              v-model="addForm.ManagementBuffer"
              style="width:100%;"
              @change="changeOptimizer"
              popper-class="select-popper"
              placeholder="请选择"
            >
              <!--              <el-option v-for="item in optimizers" :key="item.value" :label="item.label" :value="item.value">-->
              <!--              </el-option>-->
              <el-option
                v-for="item in Management"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>

          <el-form-item label="学习率" prop="learningRate">
            <el-input-number v-model="addForm.hyper_parameter.learningRate" :controls="false" />
          </el-form-item>

          <el-form-item label="权重衰减" prop="weight_decay">
            <el-input-number v-model="addForm.hyper_parameter.weight_decay" :controls="false" />
          </el-form-item>
          <el-form-item label="批次大小" prop="batch_size">
            <el-input-number v-model="addForm.hyper_parameter.batch_size" :controls="false" />
          </el-form-item>
          <el-form-item label="迭代次数" prop="epoch">
            <!--  :step="1" :step-strictly="true" -->
            <el-input-number v-model="addForm.hyper_parameter.epoch" :controls="false" />
          </el-form-item>
          <el-form-item label="梯度裁剪" prop="gradient_clip">
            <el-input-number v-model="addForm.hyper_parameter.gradient_clip" :controls="false" />
          </el-form-item>
          <el-form-item label="奖励折扣因子" prop="gamma">
            <el-input-number v-model="addForm.hyper_parameter.gamma" :controls="false" />
          </el-form-item>
          <el-form-item label="训练最大轮次" prop="maxRound">
            <el-input-number v-model="addForm.hyper_parameter.maxRound" :controls="false" />
          </el-form-item>
          <el-form-item label="模型保存频率" prop="saveFrequency">
            <el-input-number v-model="addForm.hyper_parameter.saveFrequency" :controls="false" />
          </el-form-item>

          <!-- <el-form-item label="启动命令行" prop="command">
              <el-input type="textarea" @input="onInput" :rows="2" v-model="simulation.command" />
          </el-form-item>-->
          <!-- <el-form-item label="端口" prop="port">
              <div class="outin-box" v-for="(e, i) in simulation_port_list" :key="i">
                  <div class="port-lis">
                      <el-radio-group v-model="e.protocol" class="port-lis-radio">
                          <el-radio :label="2">tcp</el-radio>
                          <el-radio :label="1">http</el-radio>
                      </el-radio-group>
                      <el-input type="text" v-model="e.port"  class="port-el-input" />
                  </div>
              </div>
          </el-form-item>-->
          <h3 class="add-alike-title">开发环境配置</h3>
          <div class="node-module">
            <h3 class="node-module-title">主节点</h3>
            <el-form-item label="环境" prop="mainNodeImageId">
              <el-cascader
                v-model="mainNode.image_group"
                :options="imageOptions"
                :show-all-levels="false"
                class="full-extent-select"
              ></el-cascader>
            </el-form-item>
            <el-form-item label="资源组" prop="mainProduct">
              <el-select
                v-model="mainNode.product_id"
                prop="main_product"
                class="full-extent-select"
              >
                <el-option
                  v-for="item in productOptions"
                  :value="item.id"
                  :label="item.name"
                  :key="item.id"
                ></el-option>
              </el-select>
            </el-form-item>
            <!-- <el-form-item label="数量">
                <el-input-number v-model="addForm.podNum"></el-input-number>
            </el-form-item>-->

            <div class="right-btn-box" v-if="slaveNodeList.length == 0">
              <span class="outin-handle">
                <a href="javascript:;" @click="addSlaveNode()">增加</a>
              </span>
            </div>
          </div>
          <div v-for="(tag, i) in slaveNodeList" :key="i">
            <div class="node-module">
              <h3 class="node-module-title">从节点</h3>

              <el-form-item label="环境" prop="slaveImage">
                <el-cascader
                  v-model="tag.image_group"
                  :options="imageOptions"
                  :show-all-levels="false"
                  class="full-extent-select"
                ></el-cascader>
              </el-form-item>
              <el-form-item label="资源组">
                <el-select v-model="tag.product_id" class="full-extent-select">
                  <el-option
                    v-for="item in productOptions"
                    :value="item.id"
                    :label="item.name"
                    :key="item.id"
                  ></el-option>
                </el-select>
              </el-form-item>
              <el-form-item label="数量">
                <el-input-number v-model="tag.pod_num"></el-input-number>
              </el-form-item>
              <div class="right-btn-box">
                <span class="outin-handle">
                  <a href="javascript:;" @click="delSlaveNode(i)">删除</a>
                  <a
                    href="javascript:;"
                    @click="addSlaveNode()"
                    v-if="i == slaveNodeList.length - 1"
                  >增加</a>
                </span>
              </div>
            </div>
          </div>

          <!-- <el-form-item label="状态空间">
              <el-input-number v-model="addForm.n_state"></el-input-number>
          </el-form-item>
          <el-form-item label="动作空间">
              <el-input-number v-model="addForm.n_action"></el-input-number>
          </el-form-item>-->

          <!--          <h3 class="add-alike-title">训练评估算法</h3>-->
          <!--          <el-form-item label="" prop="training_evaluation">-->
          <!--            <el-select v-model="addForm.training_evaluation" style="width:100%;" @change="changeOptimizer"-->
          <!--                       popper-class="select-popper" placeholder="请选择">-->
          <!--              <el-option v-for="item in exploration" :key="item.value" :label="item.label"-->
          <!--                         :value="item.value">-->
          <!--              </el-option>-->
          <!--            </el-select>-->
          <!--          </el-form-item>-->
        </div>
        <div v-show="active == 2">
          <h1 class="succeed-hint">创建成功</h1>
          <div class="succeed-btn">
            <a href="javascript:;" class="start" @click="startTask">启动</a>
            <a href="javascript:;" class="go" @click="toDetail">立即前往</a>
          </div>
        </div>
        <el-form-item label=" ">
          <el-button v-if="active == 1" type="primary" @click="submmit">确定</el-button>
        </el-form-item>
      </el-form>
    </div>
  </v-layout>
</template>

<script>
import { addGameExperiment, startGameExperiment } from "@/api/gameExperiment";
import { getMarketAlgorithmVersionDetail } from "@/api/marketAlgorithmVersion";
import { getAllImages, getImageDetail, getAllImageGroups } from "@/api/image";
import { mainImageRule, mainProductRule, slaveImageRule } from "@/utils/rule";
import { getAllProducts } from "@/api/product";
import { getenumItemsOP } from "../../api/gameExperiment";
import { getAllScenarios } from "@/api/scenario";
// import { getAllScenarios } from '@/api/scenario'
// import { algorithms } from '@/utils/maps'
export default {
  data() {
    return {
      active: 1,
      addForm: {
        is_webide: true,
        n_state: 100,
        n_action: 10,
        network_parameter: {},
        hyper_parameter: {
          learningRate: 0.001,
          weight_decay: 0.95,
          batch_size: 32,
          epoch: 20,
          gradient_clip: 0.9,
          gamma: 0.9,
          maxRound: 10000,
          saveFrequency: 500
        },
        evaluationTool: [],
        exploration_strategy: "",
        training_evaluation: ""
      },
      submitRules: {
        name: [
          { required: true, message: "该项为必填项" },
          { required: true, min: 1, max: 40, message: "长度在1到40个字符" }
        ],
        desc: [
          { required: true, message: "该项为必填项" },
          { required: true, min: 1, max: 200, message: "长度在1到200个字符" }
        ],
        // scenario_id: [
        //     { required: true, message: "该项为必填项" },
        // ],
        // simulation_node_group: [
        //     { required: true, message: "该项为必填项" },
        // ],
        main_image_id: [{ required: true, message: "该项为必填项" }],
        main_product: [{ required: true, message: "该项为必填项" }],
        mainNodeImageId: [
          {
            required: true,
            validator: mainImageRule.bind(this, this),
            trigger: "change"
          }
        ],
        mainProduct: [
          {
            required: true,
            validator: mainProductRule.bind(this, this),
            trigger: "change"
          }
        ],
        tagImageId: [
          {
            required: true,
            validator: slaveImageRule.bind(this, this),
            trigger: "change"
          }
        ]
        // port: [
        //   { required: true, message: "请填写端口" },
        // ]
      },
      simulation: { pod_num: 1 },
      mainNode: {
        visibility: "2",
        engine: "2",
        pod_num: 1,
        type: 0,
        imageOptions: [],
        image_id: null
      },
      slaveNodeList: [],
      simulation_port_list: [],
      imageOptions: [],
      productOptions: [],
      scenarioOptions: [],
      simulationImageOptions: [],
      modelOptions: [],
      modelVersionOptions: [],
      scenario: null,
      path: "",
      bizId: "",
      algorithmVersion_id: this.$route.query.algorithmVersion_id,
      algorithm_name: this.$route.query.algorithm_name,
      algorithm_desc: this.$route.query.algorithm_desc,
      algorithm_avatar: this.$route.query.algorithm_avatar,
      podUrl: [],
      simulationImageInit: [],
      network_parameter: [],
      // 激活函数
      activeFunc: [],
      // 优化器
      optimizers: [],
      exploration: [
        {
          key: "ExplorationStrategy",
          label: "经验缓存处理策略(Buffer Management Strategies exploration)",
          value: "Buffer-Management-Strategies exploration"
        }
      ],
      explorationItem: [
        {
          key: "ExplorationStrategy",
          label: "经验缓存处理策略(Buffer Management Strategies exploration)",
          value: "Buffer-Management-Strategies exploration"
        }
      ],
      network: [],
      ManagementBuffer: "",
      Management: [
        { label: "优先经验回放", value: "优先经验回放", key: "Management" },
        { label: "回顾经验回放", value: "回顾经验回放", key: "Management" }
      ]
    };
  },

  components: {},
  async created() {
    this.getData();
    this.getAllImageGroups();
    this.getProductList();
    this.getSimulationImage();
    this.getEnumItems();
    //this.getModelList()
  },
  async mounted() {
    this.$forceUpdate();
  },
  methods: {
    // 获取下拉选项
    async getEnumItems() {
      let res = await getenumItemsOP();
      // 算法名称
      this.algorithms = res.data.algorithm;
      // 探索策略
      this.exploration = res.data.exploration;
      //   tihs.exploration.push(this.explorationItem)
      // 网络类型
      let map = new Map();

      res.data.network.forEach(item => {
        map.set(item.value, item);
      });
      this.network = Array.from(map.values());

      // 优化器
      this.optimizer = res.data.optimizer;
    },
    handleCheckedCitiesChange() {},
    changeStructure() {
      this.network_parameter = this.network_structureOptions.filter(
        item => item.value === this.addForm.network_structure
      )[0].children;
      this.addForm.network_parameter = {};
    },
    changeActiveFunc() {},
    changeOptimizer() {},
    async setAddForm() {
      this.addForm.node_group_list = [];
      this.mainNode.type = 1;
      this.mainNode.image_id = this.mainNode.image_group[2];
      this.addForm.node_group_list.push(this.mainNode);
      for (let i = 0; i < this.slaveNodeList.length; i++) {
        this.slaveNodeList[i].type = 2;
        this.slaveNodeList[i].image_id = this.slaveNodeList[i].image_group[2];
        this.addForm.node_group_list.push(this.slaveNodeList[i]);
      }
      console.log(this.addForm.node_group_list);
      this.addForm.simulation_port_list = [];
      this.addForm.simulation_deduction_list = [];
      if (this.simulation.image_id) {
        this.addForm.simulation_port_list = this.simulation_port_list;
        this.addForm.simulation_deduction_list = [];
        this.addForm.simulation_node_group = this.simulation;
        this.addForm.simulation_node_group.image_id = this.simulation.image_id;
        this.addForm.scenario_id = this.scenario.id;
      }
      console.log("addForm", this.addForm);
    },
    avatarPath(data) {
      this.addForm.avatar = data;
    },
    onInput() {
      this.$forceUpdate();
    },
    async getAddForm(data) {
      this.addForm = data;
      this.port_list = [];
      this.slaveNodeList = [];
      for (let node of data.node_group_list) {
        if (node.type == 1) {
          this.mainNode = node;
          let res = await getImageDetail({ id: this.mainNode.image_id });
          let mainImage = res.data;
          this.mainNode.image_group = [
            mainImage.visibility.toString(),
            mainImage.engine.toString(),
            mainImage.id
          ];
        } else {
          let res = await getImageDetail({ id: node.image_id });
          let slaveImage = res.data;
          let slaveNode = node;
          slaveNode.image_group = [
            slaveImage.visibility.toString(),
            slaveImage.engine.toString(),
            slaveImage.id
          ];
          this.slaveNodeList.push(slaveNode);
        }
      }
      this.simulation = this.addForm.simulation_node_group;
      if (!this.simulation) {
        this.simulation = { pod_num: 1 };
      }
      this.scenario = this.addForm.scenario;
      this.changeSimulationImage();
      this.changeScenario(this.scenario);
      this.simulation_port_list = data.simulation_port_list;
    },
    async getData() {
      if (this.algorithmVersion_id) {
        let res = await getMarketAlgorithmVersionDetail({
          id: this.algorithmVersion_id
        });
        res.data.algorithm_version_id = this.algorithmVersion_id;
        this.getAddForm(res.data);
        this.addForm.name = this.algorithm_name;
        this.addForm.desc = this.algorithm_desc;
        this.addForm.avatar = this.algorithm_avatar;
      }
    },
    async submmit() {
      this.setAddForm();
      console.log("addForm", this.addForm);
      this.$refs.form.validate(async valid => {
        if (valid) {
          this.addForm.id = null;
          let res = await addGameExperiment({ ...this.addForm, pre_code: 1 });
          this.getAddForm(res.data);
          this.bizId = res.data.id;
          if (res && res.data) {
            this.active = 2;
          }
        }
      });
    },
    async changeSimulationImage() {
      if (this.simulation) {
        let ret = await getAllScenarios({ imageId: this.simulation.image_id });
        console.log("ret", ret.data);
        this.scenarioOptions = ret.data;
        let simulationCommand = this.simulation.command;
        if (this.simulation.image_id) {
          let res = await getImageDetail({ id: this.simulation.image_id });
          let image = res.data;
          this.simulation_port_list = image.port_list;
          this.simulation.product_id = image.product_id;
          this.simulation.command = image.command;
        }
        if (simulationCommand != null) {
          this.simulation.command = simulationCommand;
        }
      }
      // if (this.simulation) {
      //   // 模拟数据
      //   this.scenarioOptions = this.simulationImageInit.filter(item => item.value === this.simulation.image_id)[0].children
      //   this.scenario = null
      //   let ret = await getAllScenarios({ imageId: this.simulation.image_id })
      //   console.log('ret', ret.data)
      //   this.scenarioOptions = ret.data
      //   let simulationCommand = this.simulation.command;
      //   if (this.simulation.image_id) {
      //       let res = await getImageDetail({ id: this.simulation.image_id })
      //       let image = res.data
      //       this.simulation_port_list = image.port_list
      //       this.simulation.product_id = image.product_id
      //       this.simulation.command = image.command
      //   }
      //   if (simulationCommand != null) {
      //       this.simulation.command = simulationCommand
      //   }
      // }
    },
    async changeScenario(scenario) {
      if (scenario) {
        console.log(scenario);
        this.scenario = scenario;
        // 如果是新建任务通过调用想定命令接口更新仿真命令
        //this.getModelList()
        if (this.$route.query.id) {
          return;
        }
      }
    },

    async startTask() {
      await startGameExperiment({ id: this.bizId });
      this.toDetail();
    },
    toDetail() {
      console.log("addForm", this.addForm);
      let query = {
        id: this.addForm.id
      };
      this.$router.push({
        path: "/develop/code",
        query
      });
    },
    async getAllImageGroups() {
      let res = await getAllImageGroups();
      this.imageOptions = res.data;
    },
    async getProductList() {
      let res = await getAllProducts();
      this.productOptions = res.data;
    },
    async getSimulationImage() {
      let ret = await getAllImages({ visibility: "1", type: 3 });
      // 模拟数据
      // ret.data = this.simulationImageInit.filter(item => ({ name: item.name }))

      // 定义要过滤掉的name
      let namesToRemove = [
        "航天",
        "空战仿真",
        "星际争霸",
        "仿真0330",
        "MuJoCo",
        "CMANO",
        "casia20221101v7.6"
      ];
      this.simulationImageOptions = ret.data.filter(item => {
        return !namesToRemove.includes(item.name);
      });
    },
    succeedOver(data) {
      console.log(data);
    },
    // async changeMasterEngine(visibility, engine) {

    //     let ret = await getAllImages({ visibility: visibility, engine: engine, type: 1 })
    //     this.mainNode.imageOptions = ret.data
    //     this.mainNode = JSON.parse(JSON.stringify(this.mainNode))
    //     console.log('mainNode', this.mainNode)
    // },
    // async changeSlaveEngine(visibility, engine, i) {
    //     let ret = await getAllImages({ visibility: visibility, engine: engine, type: 1 })
    //     this.slaveNodeList[i].imageOptions = ret.data
    //     this.slaveNodeList = JSON.parse(JSON.stringify(this.slaveNodeList))
    // },
    addSlaveNode() {
      this.slaveNodeList.push({
        visibility: "2",
        engine: "2",
        type: 1,
        imageOptions: [],
        pod_num: 1
      });
    },
    delSlaveNode(i) {
      this.slaveNodeList.splice(i, 1);
    }
  }
};
</script>
<style lang="less" scoped>
@import "~@/assets/css/detail-add.less";

.el-input-number {
  width: 9.375rem;
}
/deep/ .el-form-item__label {
  font-size: 13px;
}
</style>
